package com.botech.framework.core.aop.log;

import java.lang.reflect.Method;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.alibaba.fastjson.JSON;
import com.botech.framework.core.aop.log.annotation.Log;


/**
 * <p>
 * 日志切面处理类
 * </p>
 */
@Aspect
public class LogAspect {
	
	private static final Logger LOGGER = LoggerFactory.getLogger(LogAspect.class);

	/**
	 * 日志切入点
	 */
	@Autowired
	private LogPoint logPoint;

	/**
	 * 保存系统操作日志
	 *
	 * @param joinPoint
	 *            连接点
	 * @return 方法执行结果
	 * @throws Throwable
	 *             调用出错
	 */
	@Around(value = "@annotation(com.botech.framework.core.aop.log.annotation.Log)")
	public Object saveLog(ProceedingJoinPoint joinPoint) throws Throwable {
		/**
		 * 解析Log注解
		 */
		String methodName = joinPoint.getSignature().getName();
		Method method = currentMethod(joinPoint, methodName);
		Log log = method.getAnnotation(Log.class);

		/**
		 * 日志入库
		 */
		if (log != null && log.isSaved()) {
			logPoint.saveLog(joinPoint, methodName, log.desc());
		}else{
			//获取参数列表
			Object[] args = joinPoint.getArgs();
			LOGGER.info(method.getDeclaringClass().toString() + " 调用,入参列表为 " + JSON.toJSONString(args));
		}
		Object obj = joinPoint.proceed();
		
		LOGGER.info(method.getDeclaringClass().toString() + " 调用后，返回结果为 " + JSON.toJSONString(obj));
		/**
		 * 方法执行
		 */
		return obj;
	}

	/**
	 * 获取当前执行的方法
	 *
	 * @param joinPoint
	 *            连接点
	 * @param methodName
	 *            方法名称
	 * @return 方法
	 */
	private Method currentMethod(ProceedingJoinPoint joinPoint, String methodName) {
		/**
		 * 获取目标类的所有方法，找到当前要执行的方法
		 */
		Method[] methods = joinPoint.getTarget().getClass().getMethods();
		Method resultMethod = null;
		for (Method method : methods) {
			if (method.getName().equals(methodName)) {
				resultMethod = method;
				break;
			}
		}
		return resultMethod;
	}
	
}
